#include "CCStreamServer.h"
#include <stdio.h>

bool CCStreamServer::m_bServerRunning = true;

CCStreamServer::CCStreamServer()
{
    printf("hello CCStreamServer\n");
}

CCStreamServer::~CCStreamServer()
{
    printf("~CCStreamServer()\n");
    closeListenSockFd();
}

void CCStreamServer::closeListenSockFd()
{
    if (m_listenSockFd >= 0) {
        close(m_listenSockFd);
        m_listenSockFd = -1;
    }
}

void CCStreamServer::startTCPServer()
{
    m_listenSockFd = socket(AF_INET, SOCK_STREAM, 0);
    if (m_listenSockFd < 0) {
        perror("socket");
        closeListenSockFd();
    }
    printf("start server listen socket success. sockfd:%d\n", m_listenSockFd);

    // 快速绑定
    int opt = 1;
    int len  = sizeof(opt);
    if (setsockopt(m_listenSockFd, SOL_SOCKET, SO_REUSEADDR, &opt, len) < 0) {
        perror("setsockopt");
        closeListenSockFd();
    }

    // 设置非阻塞
    fcntl(m_listenSockFd, F_SETFL, O_NONBLOCK); 

    // 绑定IP端口
    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(LISTEN_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    int ret = bind(m_listenSockFd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0) {
        perror("bind");
        closeListenSockFd();
        return;
    }
    printf("start server bing success.\n");

    // 监听
    ret = listen(m_listenSockFd, 10);
    if (ret == -1) {
        perror("listen");
        closeListenSockFd();
        return;
    }
    printf("start server listen ok.\n");

    signal(SIGINT, serverExitSignalProcess);
    while (m_bServerRunning) {
        struct sockaddr_in client_addr;
        bzero(&client_addr, sizeof(client_addr));
        socklen_t size = sizeof(struct sockaddr_in);
        int sockFd = accept(m_listenSockFd, (struct sockaddr *)&client_addr, &size);
        if (sockFd > 0) {
            printf("\n==================== NEW CONNECT ====================\n");
            printf("> connect socket %d, ip_addr:%s\n", sockFd, inet_ntoa(client_addr.sin_addr));
            CCClientProcess* clientProcess = new CCClientProcess();
            clientProcess->StartClientProcessWithSockfd(sockFd);
            m_clients.push_back(clientProcess);
        }
        printf("start listenning client ...\n");
        usleep(1000 * 2000);
    }
    return;
}

void CCStreamServer::serverExitSignalProcess(int num)
{
    printf("\nSIGINT ctl + c\n");
    m_bServerRunning = false;
}